package com.yanxu.lock.readwrite;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author 折戟沉沙铁未销
 * @version V1.0
 * @date 2025/3/23-2025
 * @Description: 演示读锁进行插队的情况
 */
public class ReadJumpQueue {
    static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(false);
    static ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
    static ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();

    public static void read() {
        System.out.println(Thread.currentThread().getName() + " 尝试获取读锁!");
        readLock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + " 获取到了读锁!");
            Thread.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.println(Thread.currentThread().getName() + " 释放了读锁!");
            readLock.unlock();
        }
    }

    public static void write() {
        System.out.println(Thread.currentThread().getName()+" 尝试获取写锁!");
        writeLock.lock();
        try {
            System.out.println(Thread.currentThread().getName()+" 获取到了写锁!");
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.println(Thread.currentThread().getName() + " 释放了写锁!");
            writeLock.unlock();
        }
    }

    public static void main(String[] args) {
        new Thread(() -> {
            write();
        }, "线程1").start();

        new Thread(() -> {
            read();
        }, "线程2").start();

        new Thread(() -> {
            read();
        }, "线程3").start();

        new Thread(() -> {
            write();
        }, "线程4").start();

        new Thread(() -> {
            read();
        }, "线程5").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                List<Thread> list=new ArrayList<>();
                for (int i = 0; i < 2000; i++) {
                    Thread thread = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            read();
                        }
                    }, "子线程创建的线程" + i);
                    list.add(thread);
                }
                for (int i = 0; i < list.size(); i++) {
                    list.get(i).start();
                }
            }
        }).start();
    }

}


/*
* 线程1 尝试获取写锁!
线程1 获取到了写锁!
线程2 尝试获取读锁!
线程3 尝试获取读锁!
线程4 尝试获取写锁!
线程5 尝试获取读锁!
子线程创建的线程0 尝试获取读锁!
子线程创建的线程1 尝试获取读锁!
子线程创建的线程2 尝试获取读锁!
子线程创建的线程3 尝试获取读锁!
子线程创建的线程4 尝试获取读锁!
子线程创建的线程5 尝试获取读锁!
子线程创建的线程6 尝试获取读锁!
子线程创建的线程7 尝试获取读锁!
子线程创建的线程8 尝试获取读锁!
子线程创建的线程9 尝试获取读锁!
子线程创建的线程10 尝试获取读锁!
线程1 释放了写锁!
线程2 获取到了读锁!
线程2 释放了读锁!
子线程创建的线程977 尝试获取读锁!
子线程创建的线程986 尝试获取读锁!
子线程创建的线程972 尝试获取读锁!
子线程创建的线程991 尝试获取读锁!
子线程创建的线程982 尝试获取读锁!
子线程创建的线程999 尝试获取读锁!
子线程创建的线程1335 获取到了读锁!
子线程创建的线程1300 获取到了读锁!
子线程创建的线程1339 获取到了读锁!
线程3 获取到了读锁!
子线程创建的线程1282 获取到了读锁!
* */